﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Minecraft.ContentInstaller;

namespace Minecraft.ModInstaller
{
    public partial class MainWindow : Form
    {
        private MinecraftContentManager ContentManager;
        private string JarPath;

        private static string n = Environment.NewLine;

        public MainWindow()
        {
            InitializeComponent();

            AutoSetupCM();
        }

        public MainWindow(string[] Args)
        {
            InitializeComponent();

            if (Args.Contains("-server"))
            {
                OpenFileDialog JarDialog = new OpenFileDialog();
                JarDialog.Title = "Open Minecraft executable";
                JarDialog.Filter = "Java executables|*.jar";
                if (JarDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    try
                    {
                        ContentManager = new MinecraftContentManager(JarDialog.FileName);
                        JarPath = JarDialog.FileName;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Unable to open the selected executable:\n\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("You must select a Minecraft executable to install content.\n\n" +
                        "If you're trying to install to the game client, remove the -server switch from the command line.",
                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                AutoSetupCM();
            }
        }

        private void AutoSetupCM()
        {
            try
            {
                ContentManager = new MinecraftContentManager();
                JarPath = MinecraftPaths.Jar;
            }
            catch (System.IO.FileNotFoundException)
            {
                MessageBox.Show("Your Minecraft installation couldn't be located.\n\n" +
                    "Please select your minecraft.jar or minecraft_server.jar file.",
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                OpenFileDialog JarDialog = new OpenFileDialog();
                JarDialog.Title = "Open Minecraft executable";
                JarDialog.Filter = "Java executables|*.jar";
                if (JarDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    try
                    {
                        ContentManager = new MinecraftContentManager(JarDialog.FileName);
                        JarPath = JarDialog.FileName;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Unable to open the selected executable:\n\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("You must select a Minecraft executable to install content.",
                           "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void OnShown(object sender, EventArgs e)
        {
            if (ContentManager == null)
                Application.Exit();

            UpdateLastBackup();
        }
        private void UpdateLastBackup()
        {
            BackupTool Tool = new BackupTool(JarPath);
            BQuickRestore.Enabled = (Tool.BackupCount > 0);
            if (BQuickRestore.Enabled)
                HintRestore.Text = String.Format("({0})", Tool.LatestBackup.GivenName + " - installed " + Tool.LatestBackup.Stamp.ToString("g"));
            else
                HintRestore.Text = "Backups will be automatically created when you install mods.";
            Tool.Dispose();
        }

        private void OnClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                ContentManager.Close();
            }
            catch { }
            try
            {
                //Delete temp data
                string TempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                    "MinecraftTools\\Temp\\");
                DeleteContents(TempPath);
            }
            catch { }
        }

        private void DeleteContents(string Folder)
        {
            foreach (string f in Directory.GetFiles(Folder))
                File.Delete(f);
            foreach (string d in Directory.GetDirectories(Folder))
            {
                DeleteContents(d);
                Directory.Delete(d);
            }
        }

        #region Installation

        private InputWrangler Input;

        private void InstallZip(object sender, EventArgs e)
        {
            OpenFileDialog OFD = new OpenFileDialog();
            OFD.RestoreDirectory = true;
            OFD.Filter = "Zip files|*.zip";
            if(OFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Input = new InputWrangler(OFD.FileName, InputWrangler.InputType.ZipFolder);

                ModName.Text = OFD.SafeFileName.Substring(0, OFD.SafeFileName.LastIndexOf('.'));
                QuickStart.Visible = false;

                ShowInfo();
            }
        }
        private void InstallFolder(object sender, EventArgs e)
        {
            FolderBrowserDialog FBD = new FolderBrowserDialog();
            FBD.Description = "Select the folder containing the files you want to add to Minecraft.";
            FBD.ShowNewFolderButton = false;
            if (FBD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Input = new InputWrangler(FBD.SelectedPath, InputWrangler.InputType.Folder);

                ModName.Text = FBD.SelectedPath.Substring(FBD.SelectedPath.LastIndexOf('\\') + 1);
                QuickStart.Visible = false;

                ShowInfo();
            }
        }
        private void InstallFile(object sender, EventArgs e)
        {
            OpenFileDialog OFD = new OpenFileDialog();
            OFD.RestoreDirectory = true;
            OFD.Filter = "Code and graphics|*.png;*.class|All files|*";
            if (OFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Input = new InputWrangler(OFD.FileName, InputWrangler.InputType.File);

                ModName.Text = OFD.SafeFileName.Substring(0, OFD.SafeFileName.LastIndexOf('.'));
                QuickStart.Visible = false;

                OutputText.Text = "You're installing the file \"" + OFD.SafeFileName + "\".";
                if (OFD.SafeFileName.EndsWith(".zip") || OFD.SafeFileName.EndsWith(".rar"))
                    OutputText.Text += n + n + "This will place the archive file directly inside Minecraft. " + 
                        "If the archive file contains the data you're trying to install, choose Install from Archive instead.";
            }
        }

        private void ShowInfo()
        {
            MagicButton.Text = "Install now";
            OutputText.Text = String.Empty;
            switch (Input.GuessedContentType)
            {
                case InputWrangler.ContentType.Skin:
                    OutputText.Text += "You're installing a Graphics Pack.";
                    break;
                case InputWrangler.ContentType.Mod:
                    OutputText.Text += "You're installing a Mod." + n + n +
                        "This will modify the game's behaviour. You should only install mods that you trust." + n +
                        "Mods made for previous versions of Minecraft may stop the game from working.";
                    break;
                case InputWrangler.ContentType.Unknown:
                    OutputText.Text += "The file you selected does not contain any graphics or code." + n + n +
                        "You can continue installation, but it may not work as advertised or do what you expect.";
                    break;
            }
            OutputText.Text += Environment.NewLine + Environment.NewLine;

            OutputText.Text += "Files to install: " + Environment.NewLine;

            ShowInfoRecursive(Input.ProbableRoot, 0);
        }
        private void ShowInfoRecursive(string InstallSource, int depth)
        {
            foreach (string file in Directory.GetFiles(InstallSource))
            {
                for (int i = 1; i <= depth; i++)
                    OutputText.Text += "  ";
                OutputText.Text += file.Substring(Input.ProbableRoot.Length) + n;
            }
            foreach (string dir in Directory.GetDirectories(InstallSource))
            {
                for (int i = 1; i <= depth; i++)
                    OutputText.Text += "  ";
                OutputText.Text += "-";
                OutputText.Text += dir.Substring(Input.ProbableRoot.Length) + n;
                ShowInfoRecursive(dir, depth+1);
            }
        }

        private void Install(object sender, EventArgs e)
        {
            this.MagicButton.Enabled = false;
            //Backup
            OutputText.Text = "Creating backup...";

            BackupTool Tool = new BackupTool(JarPath);
            try
            {
                Tool.Backup(ModName.Text);
            }
            catch {
                this.MagicButton.Enabled = true;
                return;
            }

            OutputText.Text += n + "Backup saved." + n + n;
            
            //Installation
            OutputText.Text += "Installing..." + n + n;
            if (Input.GuessedContentType == InputWrangler.ContentType.File)
            {
                OutputText.Text += "Adding file:   " + Input.ProbableRoot + "..." + n;
            }
            else
            {
                InstallRecursive(Input.ProbableRoot);
            }
            OutputText.Text += n + "Done!";
            MagicButton.Text = "Installed";
            UpdateLastBackup();
        }
        private void InstallRecursive(string Source)
        {
            foreach (string file in Directory.GetFiles(Source))
            {
                OutputText.Text += "File:      " + file.Substring(Input.ProbableRoot.Length + 1) + n;
                ContentManager.AddFile(new MinecraftContentInfo { Source = file, Destination = file.Substring(Input.ProbableRoot.Length + 1) });
            }

            foreach (string dir in Directory.GetDirectories(Source))
            {
                OutputText.Text += n + "Directory: " + dir.Substring(Input.ProbableRoot.Length + 1) + n;
                ContentManager.AddDirectory(dir.Substring(Input.ProbableRoot.Length + 1));
                InstallRecursive(dir);
            }
        }

        #endregion


        #region Menu

        #region App

        private void ShowStartPage(object sender, EventArgs e)
        {
            QuickStart.Visible = true;
        }

        private void ShowWebsite(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://minecraft.codeplex.com/");
        }

        private void AboutClick(object sender, EventArgs e)
        {
            MessageBox.Show(
                "Minecraft Mod Installer, by Dave Kellaway\nVersion " + Application.ProductVersion.ToString() +
                "\n\nDownload more free Minecraft-related software:\nhttp://minecraft.codeplex.com/\n\n" +
                "Uses SharpZipLib\nCopyright © 2000-2009 IC#Code\n\n" +
                "Creeper face from the Painterly Pack:\nhttp://painterlypack.net",
                "About", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void QuitClick(object sender, EventArgs e)
        {
            Application.Exit();
        }

        #endregion

        #region Backups

        private void RestoreLastBackup(object sender, EventArgs e)
        {
            ContentManager.Close();

            BackupTool Tool = new BackupTool(JarPath);
            Tool.RestoreLast();

            ContentManager.Open();
        }

        private void ViewBackups(object sender, EventArgs e)
        {
            ContentManager.Close();

            BackupTool Tool = new BackupTool(JarPath);
            Tool.ShowDialog();

            UpdateLastBackup();

            ContentManager.Open();
        }

        #endregion

        #endregion

    }
}
